package com.lagou.edu.minicat;

import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.*;

/**
 * 完成Minicat 3.0版本（多线程及线程池）
 * 需求:可以请求动态资源(Servlet)
 *
 * @author gaoguangyang
 */
public class BootstrapV3 {

    private int port = 8080;

    private Map<String, HttpServlet> servletMap = new HashMap<>();

    /**
     * V3.0:实现以及动态资源的访问。
     *
     * @throws IOException
     */
    public void startV3() throws Exception {
        ServerSocket serverSocket = new ServerSocket(port);
        loadServlet();
        //定义线程池
        //线程池大小
        int corePoolSize = 10;
        //线程池最大大小
        int maximumPoolSize = 50;
        //保持活动时间
        long keepAliveTime = 100L;
        //保持活动单位
        TimeUnit unit = TimeUnit.SECONDS;
        BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(50);
        ThreadFactory threadFactory = Executors.defaultThreadFactory();
        RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();

        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
        while (true) {
            Socket accept = serverSocket.accept();
            executor.execute(new ProcessHandler(accept, servletMap));
        }
    }

    private void loadServlet() throws Exception {
        InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("web.xml");
        SAXReader saxReader = new SAXReader();

        Document document = saxReader.read(resourceAsStream);
        Element rootElement = document.getRootElement();

        List<Element> selectNodes = rootElement.selectNodes("//servlet");

        for (Element element : selectNodes) {
            Element servletNameEle = (Element) element.selectSingleNode("//servlet-name");
            String servletName = servletNameEle.getStringValue();
            Element servletClsEle = (Element) element.selectSingleNode("//servlet-class");
            String servletClass = servletClsEle.getStringValue();

            //根据servlet-name的值找到url-pattern
            Element servletMapping = (Element) rootElement.selectSingleNode("/web-app/servlet-mapping[servlet-name='" + servletName + "']");
            String urlPattern = servletMapping.selectSingleNode("url-pattern").getStringValue();

            servletMap.put(urlPattern, (HttpServlet) Class.forName(servletClass).newInstance());
        }
    }

    public static void main(String[] args) throws Exception {
        BootstrapV3 bootstrapV3 = new BootstrapV3();
        bootstrapV3.startV3();
    }
}
